import {
  Module,
  NestModule,
  MiddlewareConsumer,
  RequestMethod,
} from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { CatsModule } from './cats/cats.module';
import { CatsMiddleware, logger } from './cats/middleware/cats.middleware';
import { CatsController } from './cats/cats.controller';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule, TypeOrmModuleOptions } from '@nestjs/typeorm';
import { UserModule } from './user/user.module';
import { BooksModule } from './books/books.module';

@Module({
  imports: [
    ConfigModule.forRoot({
      envFilePath: `.env.${process.env.NODE_ENV || 'development'}`,
      isGlobal: true,
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule],
      useFactory: (configService: ConfigService) => {
        // console.log({
        //   host: configService.get<string>('DB_HOST'),
        //   port: configService.get<number>('DB_PORT'),
        //   username: configService.get<string>('DB_USERNAME'),
        //   password: configService.get<string>('DB_PASSWORD'),
        //   database: configService.get<string>('DB_DATABASE'),
        // });
        return {
          type: 'mysql',
          host: configService.get<string>('DB_HOST'),
          port: configService.get<number>('DB_PORT'),
          username: configService.get<string>('DB_USERNAME'),
          password: configService.get<string>('DB_PASSWORD'),
          database: configService.get<string>('DB_DATABASE'),
          entities: [__dirname + '/**/*.entity{.ts,.js}'],
          synchronize: configService.get<string>('NODE_ENV') === 'development', // 仅在开发环境中同步
        };
      },
      inject: [ConfigService], // 注入 ConfigService
    }),
    CatsModule,
    UserModule,
    BooksModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
// 应用中间件
export class AppModule implements NestModule {
  // MiddlewareConsumer 是一个辅助类。它提供了几种内置的方法来管理中间件。
  configure(consumer: MiddlewareConsumer) {
    // consumer.apply(CatsMiddleware).forRoutes('cats');
    // get请求 /cats
    // consumer.apply(CatsMiddleware).forRoutes({
    //   path: 'cats',
    //   method: RequestMethod.GET,
    // });
    // forRoutes() 方法可以接受单个字符串、多个字符串、一个 RouteInfo 对象、一个控制器类甚至多个控制器类
    // consumer.apply(CatsMiddleware).forRoutes(CatsController);

    // 排除路由，exclude() 方法接受单个字符串、多个字符串或 RouteInfo 对象来标识要排除的路由。
    consumer
      .apply(logger, CatsMiddleware) //为了绑定顺序执行的多个中间件，只需在 apply() 方法中提供一个逗号分隔的列表
      //   .exclude({ path: 'cats', method: RequestMethod.GET })
      .forRoutes(CatsController);
  }
}
